#include <vtkForceDirectedLayoutStrategy.h>
#include <vtkGraphLayoutView.h>
#include <vtkMutableUndirectedGraph.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>

#include <vtkArcSource.h>
#include <vtkPolyDataMapper.h>
#include "vtkPolygon.h"
#include "vtkProperty.h"

#include "vtkLookupTable.h"
#include "vtkMinimalStandardRandomSequence.h"
#include "vtkCellData.h"
#include "vtkSphereSource.h"
#include "vtkTubeFilter.h"
#include "vtkLineSource.h"

#include "vtkInteractorStyleTrackballCamera.h"


int main(int, char*[]) {

//    vtkNew<vtkNamedColors> colors;
//
//    // Create a sphere
//    vtkNew<vtkSphereSource> sphereSource;
//    sphereSource->SetCenter(0.0, 0.0, 0.0);
//    sphereSource->SetRadius(5.0);
//    // Make the surface smooth.
//    sphereSource->SetPhiResolution(100);
//    sphereSource->SetThetaResolution(100);
//
//    vtkNew<vtkPolyDataMapper> mapper;
//    mapper->SetInputConnection(sphereSource->GetOutputPort());
//
//    vtkNew<vtkActor> actor;
//    actor->SetMapper(mapper);
//    actor->GetProperty()->SetColor(colors->GetColor3d("Cornsilk").GetData());
//
//    vtkNew<vtkRenderer> renderer;
//    vtkNew<vtkRenderWindow> renderWindow;
//    renderWindow->SetWindowName("Sphere");
//    renderWindow->AddRenderer(renderer);
//    vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
//    renderWindowInteractor->SetRenderWindow(renderWindow);
//
//    renderer->AddActor(actor);
//    renderer->SetBackground(colors->GetColor3d("DarkGreen").GetData());
//
//    renderWindow->Render();
//    renderWindowInteractor->Start();

// Create a line
    vtkSmartPointer<vtkLineSource> lineSource =
            vtkSmartPointer<vtkLineSource>::New();
    lineSource->SetPoint1(1.0, 0.0, 0.0);
    lineSource->SetPoint2(0.0, 1.0, 0.0);

    // Create a mapper and actor
    vtkSmartPointer<vtkPolyDataMapper> lineMapper =
            vtkSmartPointer<vtkPolyDataMapper>::New();
    lineMapper->SetInputConnection(lineSource->GetOutputPort());
    vtkSmartPointer<vtkActor> lineActor =
            vtkSmartPointer<vtkActor>::New();
    lineActor->GetProperty()->SetColor(0.0,0.0,0.1); // Give some color to the line
    lineActor->SetMapper(lineMapper);

    // Create a tube (cylinder) around the line
    vtkSmartPointer<vtkTubeFilter> tubeFilter =
            vtkSmartPointer<vtkTubeFilter>::New();
    tubeFilter->SetInputConnection(lineSource->GetOutputPort());
    tubeFilter->SetRadius(.025); //default is .5
    tubeFilter->SetNumberOfSides(50);
    tubeFilter->Update();

    // Create a mapper and actor
    vtkSmartPointer<vtkPolyDataMapper> tubeMapper =
            vtkSmartPointer<vtkPolyDataMapper>::New();
    tubeMapper->SetInputConnection(tubeFilter->GetOutputPort());
    vtkSmartPointer<vtkActor> tubeActor =
            vtkSmartPointer<vtkActor>::New();
    tubeActor->GetProperty()->SetOpacity(0.5); //Make the tube have some transparency.
    tubeActor->SetMapper(tubeMapper);

    // Create a renderer, render window, and interactor
    vtkSmartPointer<vtkRenderer> renderer =
            vtkSmartPointer<vtkRenderer>::New();
    vtkSmartPointer<vtkRenderWindow> renderWindow =
            vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);
    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
            vtkSmartPointer<vtkRenderWindowInteractor>::New();
    renderWindowInteractor->SetRenderWindow(renderWindow);

    // Add the actor to the scene
    renderer->AddActor(tubeActor);
    renderer->AddActor(lineActor);
    renderer->SetBackground(0,1,0);

    // Render and interact
    renderWindow->Render();
    renderWindowInteractor->Start();

    return EXIT_SUCCESS;
}